package com.example.design.c.temp;

import cn.hutool.core.util.RandomUtil;

/**
 * 抽象类/抽象模板（Abstract Class）
 * 抽象模板类，负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
 * 银行业务父类
 * 封装了去银行办理业务所需要的基本步骤
 */
public abstract class AbstractBankBusiness {

    /**
     * 模板方法(除这个方法之外的方法统称为基本方法)
     * 定义了算法的骨架，按某种顺序调用其包含的基本方法。
     */
    public void business() {
        // 取号
        Integer num = getNumber();
        System.out.println("排队取号: " + num);
        // 叫号
        callNumber(num);
        // 办理业务
        Integer cash = personalBusiness();
        // 通过钩子方法父类方法逻辑可控
        if (saveMoney(cash)) { // 存款超过10000赠送礼物
            gift();
        }
        // 作出评价
        rank();
    }

    /*
     * 基本方法：是整个算法中的一个步骤，包含以下几种类型。
     * 抽象方法：在抽象类中声明，由具体子类实现。
     * 具体方法：在抽象类中已经实现，在具体子类中可以继承或重写它。
     * 钩子方法：在抽象类中已经实现，包括用于判断的逻辑方法和需要子类重写的空方法两种。
     */

    /**
     * 取号排队
     */
    protected Integer getNumber() {
        return RandomUtil.randomInt(1000, 10000);
    }

    /**
     * 叫号
     */
    protected void callNumber(Integer sortNum) {
        System.out.println("请" + sortNum + "号上前办理业务");
    }

    /**
     * 个人业务
     */
    protected abstract Integer personalBusiness();

    /**
     * 钩子方法
     * 赠送礼物逻辑
     */
    protected void gift() {
    }

    /**
     * 钩子方法
     * 存钱业务逻辑判断
     *
     * @return
     */
    protected boolean saveMoney(Integer cash) {
        if (cash == null) {
            cash = 0;
        }
        if (cash >= 10000) {
            System.out.println("存钱等于或超过10000元的赠送礼品, 已满足条件");
            return true;
        }
        return false;
    }

    /**
     * 评价服务
     */
    protected void rank() {
        System.out.println("请对我的服务作出评价: 满意 10 分, 不满意 1 分");
        System.out.println("==============================================================");
    }
}
